package com.yc154.bank.biz;

import com.yc154.bank.entity.Account;
import com.yc154.bank.entity.Oprecord;
import com.yc154.bank.mapper.AccoutDao;
import com.yc154.bank.mapper.OprecordMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.jdbc.DataSourceBuilder;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.stereotype.Service;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.support.DefaultTransactionDefinition;

import javax.sql.DataSource;
import java.beans.Transient;
import java.time.LocalDateTime;

@Service
@Transactional(rollbackFor = BizException.class)
public class BankBiz {
    @Autowired
    private AccoutDao accoutDao;

    @Autowired
    private OprecordMapper oprecordMapper;

    @Autowired
    DataSource dataSource;

    // 存款(deposit), 取款(withdraw), 转账(transfer), 开户(register), 查询(query)
    public void deposit(Long aid, Double money) {
        // 开启事务
        PlatformTransactionManager transactionManager
                = new DataSourceTransactionManager(dataSource);
        // 定义事务属性
        TransactionDefinition transactionDefinition
                = new DefaultTransactionDefinition();
        // 获取事务状态
        TransactionStatus status = transactionManager.getTransaction(transactionDefinition);
        try{
            // 1. 查询账户
            Account account = accoutDao.selectById(aid);
            // 2. 存款
            account.setBalance(account.getBalance() + money);
            // 3. 更新账户
            accoutDao.updateById(account);
            Oprecord oprecord = new Oprecord();
            oprecord.setAid(aid);
            oprecord.setOpmoney(money);
            oprecord.setOptime(LocalDateTime.now());
            oprecord.setRemark("存款");

            // int i = 1 / 0; // 人为制造异常

            // 4. 记录操作日志
            oprecordMapper.insert(oprecord);
            transactionManager.commit(status);
        } catch (Exception e){
            e.printStackTrace();
            transactionManager.rollback(status);
        }
    }

    @Transactional(rollbackFor = BizException.class)
    public void withdraw(Long aid, Double money) throws BizException{
        // 1. 查询账户
        Account account = accoutDao.selectById(aid);
        // 1.1 校验账户是否存在
        if(account == null){
            throw new BizException("账户不存在");
        }
        // 1.2 校验账户余额是否充足
        if(account.getBalance() < money){
            throw new BizException("账户余额不足");
        }
        // 2. 取款
        account.setBalance(account.getBalance() - money);
        // 3. 更新账户
        accoutDao.updateById(account);
        Oprecord oprecord = new Oprecord();
        oprecord.setAid(aid);
        oprecord.setOpmoney(money);
        oprecord.setOptime(LocalDateTime.now());
        oprecord.setRemark("取款");

        // int i = 1 / 0; // 人为制造异常
//        if(money == 500){
//            throw new BizException("不能存款500元");
//        }

        // 4. 记录操作日志
        oprecordMapper.insert(oprecord);
    }

    public void transfer(Long fromAid, Long toAid, Double money) throws BizException {
        withdraw(fromAid, money);
        deposit(toAid, money);
    }

    public void register(String aid, String pwd, Double money) {

    }

    public void query(Long aid) {

    }
}
